<?php
namespace App\Services;

use App\Lib\Util\QueryPager;
use App\Activity;
use App\City;
use App\User;
use App\UserGroup;
use App\ActivityGroup;
use App\ActivityCity;
use App\ActivityAuditRequest;
use App\BaseDictionary;
use Carbon\Carbon;
use App\UserActivityRequests;
use App\UserActivity;
use DB;

class ActivityService
{
    /**
     * 构建一个用于查询的基本query，这样以后所有需要查询的地方就不需要重写该query
     */
    private function baseQuery($auditStatus)
    {
        return Activity::whereIn('audit_status', $auditStatus);
    }

    public function getTotalVolunteerCount()
    {
        //return
    }

    public function getTotalTeamCount()
    {
        return UserGroup::where('volunteer_group_flag', UserGroup::$GROUP_FLAG_ACTIVE)->count();
    }


    public function getActivities(Array $input, Array $auditStatus, $paging = true)
    {
        $query = $this->baseQuery($auditStatus);

        if (!empty($input['subject'])) {
            $query = $query->where('subject', 'like', '%' . $input['subject'] . '%');
        }

        if (!empty($input['code'])) {
            $query = $query->where('code', 'like', '%' . $input['code'] . '%');
        }

        if (!empty($input['activityType'])) {
            $query = $query->where('activity_type', $input['activityType']);
        }

        if (!empty($input['cityId'])) {
            $query = $query->whereHas('cities', function ($query) use ($input) {
                $query->where('cities.id', $input['cityId']);
            });
        }

        if (!empty($input['startCreateDt'])) {
            $query = $query->where('created_at', '>=', $input['startCreateDt']);
        }

        if (!empty($input['endCreateDt'])) {
            $query = $query->where('created_at', '<=', $input['endCreateDt']);
        }

        if (!empty($input['startActiveDt'])) {
            $query = $query->where('active_time_start', '>=', $input['startActiveDt']);
        }

        if (!empty($input['endActiveDt'])) {
            $query = $query->where('active_time_end', '<=', $input['endActiveDt']);
        }

        if (!empty($input['minVolunteerNum'])) {
            $query = $query->where('min_volunteer_num', '>=', $input['minVolunteerNum']);
        }

        if (!empty($input['status'])) {
            $query = $query->where('status', $input['status']);
        }

        if (!empty($input['volunteerGroupInfo'])) {
            $query = $query->whereHas('groups', function ($query) use ($input) {
                $query->where('user_groups.name', 'like', '%' . $input['volunteerGroupInfo'] . '%')
                    ->orWhere('user_groups.code', 'like', '%' . $input['volunteerGroupInfo'] . '%')
                    ->orWhere('user_groups.business_code', 'like', '%' . $input['volunteerGroupInfo'] . '%');
            });
        } else if (!empty($input['groupId'])) {
            $query = $query->whereHas('groups', function ($query) use ($input) {
                $query->where('user_groups.id', $input['groupId']);
            });
        }

        $pager = new QueryPager($query);

        $pager->mapField('activity_type', Activity::$ACTIVITY_TYPE_MAP);
        $pager->mapField('join_method', Activity::$USER_JOIN_PERMIT_TYPE_MAP);
        $pager->mapField('audit_status', Activity::$AUDIT_STATUS_MAP);
        $pager->mapField('status', Activity::$STATUS_MAP);

        $pager->setRefectionMethodField('majorGroup');
        $pager->setRefectionMethodField('getAllCityName');
        $pager->setRefectionMethodField('getAllGroupsName');
        $pager->setRefectionMethodField('majorGroupIconFull');
        $pager->setRefectionMethodField('getFullPicturePath');
        $pager->setRefectionMethodField('isPartyActivity');
        $pager->setRefectionMethodField('isCommunityActivity');

        return $paging ? $pager->doPaginate($input, 'enter_time_start') :
            $pager->queryWithoutPaginate($input, 'enter_time_start');
    }

    public function getActivityDetail(Array $input)
    {
        $query = Activity::where('id', '=', $input['id']);
        $pager = new QueryPager($query);
        $pager->mapField('activity_type', Activity::$ACTIVITY_TYPE_MAP);
        $pager->mapField('join_method', Activity::$USER_JOIN_PERMIT_TYPE_MAP);
        $pager->mapField('audit_status', Activity::$AUDIT_STATUS_MAP);
        $pager->mapField('status', Activity::$STATUS_MAP);
        $pager->setRefectionMethodField('getFullPicturePath');
        $pager->setRefectionMethodField('majorGroupIconFull');
        $pager->setRefectionMethodField('majorGroup');
        $result = $pager->queryWithoutPaginate($input, 'enter_time_start');
        return $result ? $result[0] : [];
    }

    public function toAuditActivity($activityId)
    {
        DB::transaction(function () use ($activityId) {
            $activity = Activity::findOrFail($activityId);

            $activity->audit_status = Activity::$AUDIT_STATUS_TOAUDIT;
            $activity->save();

            ActivityAuditRequest::create([
                'activity_id'  => $activity->id,
                'request_time' => Carbon::now()
            ]);
        });

    }

    public function toDoAuditActivity($activityId)
    {
        DB::transaction(function () use ($activityId) {
            $activity = Activity::findOrFail($activityId);

            $activity->audit_status = Activity::$AUDIT_STATUS_PERMITTED;
            $activity->save();

            $auditRequest = ActivityAuditRequest::where('activity_id', $activityId)->orderBy('request_time', 'desc')->first();

            if (isset($auditRequest)) {
                $auditRequest->process_result = BaseDictionary::$KEY_YES;
                $auditRequest->process_time   = Carbon::now();
                $auditRequest->save();
            }
        });

    }

    public function isActivityBelongToCurrentOrg($activityId, $groupId)
    {
        return ActivityGroup::where('activity_id', $activityId)->where('group_id', $groupId)->count() > 0;
    }

    public function getProperlyCities($groupId)
    {
        $group = UserGroup::findOrFail($groupId);

        if ($group->isExternalEnterprise()) {
            $groupCityId = $group->city_id;

            $cityIds = Activity::select('activity_cities.city_id')->join('activity_groups', function ($join) {
                $join->on('activities.id', '=', 'activity_groups.activity_id');
            })->join('activity_cities', function ($join) {
                $join->on('activities.id', '=', 'activity_cities.activity_id');
            })->where('activity_groups.group_id', $groupId)->groupBy('activity_cities.city_id')->get()->pluck('city_id')->toArray();

            array_push($cityIds, $groupCityId);

            return City::whereIn('id', $cityIds)->orderBy('sort_order')->get();
        } else if ($group->isInternalOrganization()) {
            return City::orderBy('sort_order')->get();
        }

        return null;
    }

    public function createActivity($data, $cityIds, $groupIds)
    {
        DB::transaction(function () use ($data, $cityIds, $groupIds) {
            $activity = Activity::create([
                'code'              => $this->getActivityCode(),
                'subject'           => $data['subject'],
                'picture'           => $data['picture'],
                'enter_time_start'  => $data['enter_time_start'],
                'enter_time_end'    => $data['enter_time_end'],
                'active_time_start' => $data['active_time_start'],
                'active_time_end'   => $data['active_time_end'],
                'activity_type'     => $data['activity_type'],
                'volunteer_num'     => $data['volunteer_num'],
                'join_method'       => $data['join_method'],
                'volunteer_rule'    => $data['volunteer_rule'],
                'description'       => $data['description'],
                'min_volunteer_num' => $data['min_volunteer_num'],
                'time_length'       => $data['time_length'],
            ]);

            $activity->audit_status = Activity::$AUDIT_STATUS_DRAFT;
            $activity->status       = Activity::$STATUS_UNSTART;
            $activity->save();

            $sortOrder = 1;
            foreach ($cityIds as $cityId) {
                if (!empty($cityId)) {
                    ActivityCity::create([
                        'city_id'     => $cityId,
                        'activity_id' => $activity->id,
                        'description' => $data['description'],
                        'sort_order'  => $sortOrder
                    ]);
                    $sortOrder++;
                }
            }

            $sortOrder = 1;
            foreach ($groupIds as $groupId) {
                if (!empty($groupId)) {
                    $activityGroup = ActivityGroup::create([
                        'group_id'    => $groupId,
                        'activity_id' => $activity->id,
                        'sort_order'  => $sortOrder
                    ]);
                    if ($sortOrder == 1) {
                        $activityGroup->major_flag = BaseDictionary::$KEY_YES;
                    } else {
                        $activityGroup->major_flag = BaseDictionary::$KEY_NO;
                    }
                    $activityGroup->save();
                    $sortOrder++;
                }
            }
        });
    }

    public function getActivityCode()
    {
        if (Activity::count() > 0) {
            $lastCode = Activity::max('code');

            $codeVal = intval($lastCode);

            $nextVal = $codeVal + 1;

            $strCodeVal = strval($nextVal);

            $len = 12 - strlen($strCodeVal);

            for ($i = 0; $i < $len; $i++) {
                $strCodeVal = '0' . $strCodeVal;
            }

            return $strCodeVal;
        }

        return '000000000001';
    }

    /*
    * name:报名活动
    * author:hy
    * param:$request
    */
    public function applyJoinActivity($data)
    {
        DB::transaction(function () use ($data) {
            $applyJoinInfo = UserActivityRequests::create([
                'user_id'      => $data['user_id'],
                'activity_id'  => $data['activity_id'],
                'city_id'      => $data['city_id'],
                'request_time' => date('Y-m-d H:i', time()),
            ]);
        });
    }

    /*
    * name:获取活动开放状态
    * author:hy
    * param:$request
    */
    public function activityIsOpenJoin($id)
    {
        return Activity::where('id', '=', $id)->where('join_method', '=', Activity::$USER_JOIN_PERMIT_TYPE_PUBLIC)->first();
    }

    /*
    * name:判断是否已加入
    * author:hy
    * param:$request
    */
    public function isHasBeingJoin($user_id, $activity_id)
    {
        return UserActivity::where('user_id', '=', $user_id)->where('activity_id', '=', $activity_id)->first();
    }

    /*
    * name:获取用户申请活动列表
    * author:hy
    * param:$request
    */
    public function getUserApplyActivities(Array $input, $paging = true)
    {

        $query = UserActivityRequests::whereNull('process_result');
        if (!empty($input['subject'])) {
            $query = $query->whereHas('relateActivity', function ($query) use ($input) {
                $query->where('activities.subject', 'like', '%' . $input['subject'] . '%');
            });
        }

        if (!empty($input['code'])) {
            $query = $query->whereHas('relateActivity', function ($query) use ($input) {
                $query->where('activities.code', 'like', '%' . $input['code'] . '%');
            });
        }

        if (!empty($input['activityType'])) {
            $query = $query->whereHas('relateActivity', function ($query) use ($input) {
                $query->where('activities.activityType', '=', $input['activityType']);
            });
        }

        if (!empty($input['cityId'])) {
            $query = $query->whereHas('relateCity', function ($query) use ($input) {
                $query->where('cities.id', $input['cityId']);
            });
        }

        if (!empty($input['startActiveDt'])) {
            $query = $query->whereHas('relateActivity', function ($query) use ($input) {
                $query->where('activities.active_time_start', '>=', $input['startActiveDt']);
            });
        }

        if (!empty($input['endActiveDt'])) {
            $query = $query->whereHas('relateActivity', function ($query) use ($input) {
                $query->where('activities.active_time_end', '<=', $input['endActiveDt']);
            });
        }

        if (!empty($input['userName'])) {
            $query = $query->whereHas('relateUser', function ($query) use ($input) {
                $query->where('users.name', 'like', '%' . $input['userName'] . '%')->orWhere('users.nick_name', '%' . $input['userName'] . '%');
            });
        }

        if (!empty($input['volunteerGroupInfo'])) {
            $ids = UserGroup::where('name', 'like', '%' . $input['volunteerGroupInfo'] . '%')
                ->orWhere('code', 'like', '%' . $input['volunteerGroupInfo'] . '%')
                ->orWhere('business_code', 'like', '%' . $input['volunteerGroupInfo'] . '%')
                ->pluck('id')->toArray();

            $query = $query->whereHas('relateMajorGroup', function ($query) use ($input, $ids) {
                $query->whereIn('activity_groups.group_id', $ids);
            });

        }
        $pager = new QueryPager($query);

        $pager->setRefectionMethodField('cities');
        $pager->setRefectionMethodField('activities');
        $pager->setRefectionMethodField('users');
        $pager->setRefectionMethodField('majorGroup');
        return $paging ? $pager->doPaginate($input, 'id') :
            $pager->queryWithoutPaginate($input, 'id');

    }

    /*
    * name:获取用户申请活动详情
    * author:hy
    * param:$request
    */
    public function getUserApplyActivitiesDetail(Array $input)
    {
        $query = UserActivityRequests::where('id', '=', $input['id']);
        $pager = new QueryPager($query);
        $pager->setRefectionMethodField('cities');
        $pager->setRefectionMethodField('activities');
        $pager->setRefectionMethodField('users');
        $pager->setRefectionMethodField('majorGroup');
        $result = $pager->queryWithoutPaginate($input, 'id');
        return $result ? $result[0] : [];
    }

    /*
    * @name:通过用户申请
    * @author:hy
    * @param:$request
    */
    public function passUserApply(Array $input)
    {
        date_default_timezone_set('Asia/Shanghai');
        $applyInfo = UserActivityRequests::findOrFail($input['id']);
        DB::transaction(function () use ($input, $applyInfo) {
            UserActivityRequests::where('id', '=', $input['id'])
                ->update([
                    'process_time'   => date('Y-m-d H:i', time()),
                    'process_result' => UserActivityRequests::$USER_APPLY_ACTIVITY_STATUS_PASS,
                ]);

            UserActivity::create([
                'city_id'     => $applyInfo['city_id'],
                'user_id'     => $applyInfo['user_id'],
                'activity_id' => $applyInfo['activity_id'],
                'join_time'   => $applyInfo['request_time']
            ]);
        });
    }

    /*
    * @name:拒绝用户申请
    * @author:hy
    * @param:$request
    */
    public function denyUserApply(Array $input)
    {
        date_default_timezone_set('Asia/Shanghai');
        UserActivityRequests::where('id', '=', $input['id'])
            ->update([
                'process_time'   => date('Y-m-d H:i', time()),
                'process_result' => UserActivityRequests::$USER_APPLY_ACTIVITY_STATUS_DENY,
                'deny_reason' => $input['deny_reason']
            ]);
    }
}
